package org.jpass.dc.business.svn;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNCommitClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

/**
 * 控制用户项目版本
 * @author weilong peng
 *
 */
public class SVNService {
	Log log = LogFactory.getLog(SVNService.class);
	/* svn根目录  */
	private String svnRoot;
	/* 用户名称   */
	private String userName;
	/* 密码   */
	private String password;
	/* svn仓库   */
	private SVNRepository repository;
	
	private SVNURL repositoryURL = null;
	
	private SVNClientManager clientManager;
	
	public SVNService() {}
	
	public SVNService(String svnRoot) {
		this.svnRoot = svnRoot;
	}
	
	public SVNService(String svnRoot, String userName, String password) {
		this.svnRoot=svnRoot;
	    this.userName=userName;
	    this.password=password;
	}
	
	/**
	 * 通过不同的协议初始化版本库
	 */
    protected static void setupLibrary() {
       DAVRepositoryFactory.setup(); // 处理http://和https://的请求
       
       SVNRepositoryFactoryImpl.setup(); // 处理svn://和svn+xxx://的请求
       
       FSRepositoryFactory.setup(); // 处理file://的请求
    }
    
    /**
     * 登陆验证
     * @return
     */
    public boolean loginSVN() {
        setupLibrary();
        try{
            //创建库连接
            repository=SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnRoot));
            //身份验证
            ISVNAuthenticationManager authManager = SVNWCUtil
            		.createDefaultAuthenticationManager(userName, password);
            //创建身份验证管理器
            repository.setAuthenticationManager(authManager);
            return true;
        } catch(SVNException svne) {
            svne.printStackTrace();
            log.error("创建svn库连接时出现异常，", svne);
            return false;
        }
     }
    
    /**
     * 登陆验证
     * @return
     */
    public boolean loginSVN(String svnRoot, String userName, String password) {
        setupLibrary();
      //相关变量赋值
		try {
			repositoryURL = SVNURL.parseURIEncoded(svnRoot);
			ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
        	//实例化客户端管理类
	    	clientManager = SVNClientManager.newInstance(
	    			(DefaultSVNOptions) options, userName, password);
	        return true;
		} catch (SVNException svne) {
			svne.printStackTrace();
            log.error("创建svn库连接时出现异常，", svne);
            return false;
        }
     }
    
    /**
     * 查询给定路径下的条目列表
     * @param path
     * @return
     * @throws SVNException
     */
    @SuppressWarnings("rawtypes")
    public List<SVN> getEntries(String path) throws SVNException {
       Collection entries = repository.getDir(path, -1, null,
              (Collection) null);
       Iterator iterator = entries.iterator();
       List<SVN> svns = new ArrayList<SVN>();
       while (iterator.hasNext()) {
           SVNDirEntry entry = (SVNDirEntry) iterator.next();
           SVN svn = new SVN();
           svn.setCommitMessage(entry.getCommitMessage());
           svn.setDate(entry.getDate());
           svn.setKind(entry.getKind().toString());
           svn.setName(entry.getName());
           svn.setRepositoryRoot(entry.getRelativePath().toString());
           svn.setRevision(entry.getRevision());
           svn.setSize(entry.getSize()/1024);
           svn.setUrl(path.equals("") ? "/"+entry.getName() : path + "/"+entry.getName());
           svn.setAuthor(entry.getAuthor());
           svn.setState(svn.getKind() == "file"?null:"closed");
           svns.add(svn);
       }
       return svns;
    }
    
    /**
     * 把版本库中的内容check out到本地目录中
     * @param workPath
     * @param svnRoot
     * @param userName
     * @param password
     * @return
     * @throws SVNException
     */
    public Long checkOut(String workPath, String svnRoot, String userName, String password)
    		throws SVNException {
    	boolean bool = loginSVN(svnRoot, userName, password);
    	long workingVersion = -1L;
    	
    	try {
    		if (bool) {
        		File workDir = new File(workPath);
        		//通过客户端管理类获得updateClient类的实例。
        		SVNUpdateClient updateClient = clientManager.getUpdateClient();
        		/*
        		 * sets externals not to be ignored during the checkout
        		 */
        		updateClient.setIgnoreExternals(false);
        		
        		//执行check out 操作，返回工作副本的版本号。
        		workingVersion = updateClient
        				.doCheckout(repositoryURL, workDir, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, false);
        	}
		} catch (SVNException svne) {
			svne.printStackTrace();
            log.error("创建svn库连接时出现异常，", svne);
            throw svne;
        }
    	
    	return workingVersion;
    }
    
    /**
     * 将项目导入到版本库中
     * @param workPath
     * @param svnRoot
     * @param message
     * @param userName
     * @param password
     * @return
     */
    public String doImport(String workPath, String svnRoot, String message, 
    		String userName, String password) throws SVNException {
    	boolean bool = loginSVN(svnRoot, userName, password);
    	String msg = null;
    	try {
    		if (bool) {
        		File workDir = new File(workPath);
        		//通过客户端管理类获得updateClient类的实例。
        		SVNCommitClient commitClient = clientManager.getCommitClient();
        		
        		//执行check out 操作，返回工作副本的版本号。
        		SVNCommitInfo ciInfo = commitClient.
        		        doImport(workDir, repositoryURL, message, null, false, false, SVNDepth.INFINITY);
        		msg = ciInfo.getErrorMessage().getFullMessage();
        	}
		} catch (SVNException svne) {
			svne.printStackTrace();
            log.error("创建svn库连接时出现异常，", svne);
            throw svne;
        }
		
		return msg;
    }
}
